package com.ecr.hub.service.rail.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;

import com.ecr.hub.ApplicationException;
import com.ecr.hub.DaoApplicationException;
import com.ecr.hub.RailNotFoundException;
import com.ecr.hub.database.dao.IDaoDestination;
import com.ecr.hub.database.dao.IDaoRail;
import com.ecr.hub.model.destination.Destination;
import com.ecr.hub.model.rail.Rail;
import com.ecr.hub.model.rail.TypeBundle;
import com.ecr.hub.service.rail.IRailManager;

@Service("railManager")
public class RailManagerImpl implements IRailManager {

	// Le dao pour les requêtes rail.
	@Resource(name = "daoRail")
	IDaoRail daoRail;

	// Le dao pour les requêtes destination.
	@Resource(name = "daoDestination")
	IDaoDestination daoDestination;

	@Override
	public List<Rail> getAllList() throws ApplicationException {
		try {
			return daoRail.getAllList();
		} catch (EmptyResultDataAccessException e) {
			return null;
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	/**
	 * Mise à jour des propriétés de la voie. Afin d'éviter des requêtes trop
	 * complexes (pour la visualisation du Hub), on place directement les
	 * informations de la destination dans la voie. Cela complique le traitement
	 * mais permet d'éviter des OUTER JOIN au niveau de la requête.
	 */
	@Override
	public void update(Rail rail) throws ApplicationException {
		try {
			this.completeDestination(rail);
			daoRail.update(rail);
		} catch (EmptyResultDataAccessException e) {
			throw new ApplicationException(e);
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	@Override
	public List<TypeBundle> getListTypeBundle() throws ApplicationException {
		try {
			return daoRail.getListTypeBundle();
		} catch (EmptyResultDataAccessException e) {
			return null;
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	@Override
	public List<Rail> getListByTypeBundle(int id, int active)
			throws ApplicationException {
		try {
			return daoRail.getListByTypeBundle(id, active);
		} catch (EmptyResultDataAccessException e) {
			return null;
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}

	private void completeDestination(Rail rail) throws DataAccessException {
		if (rail.getDestinationId() > 0) {
			Destination destination = daoDestination.getDestinationById(rail
					.getDestinationId());
			rail.setDestinationLabel(destination.getLabel());
			rail.setDestinationHexColor(destination.getHexColor());
		} else {
			rail.setDestinationId(0);
			rail.setDestinationLabel("");
			rail.setDestinationHexColor("");
		}
	}

	/**
	 * Récupération des informations d'une voie à partir de l'identifiant
	 * interne de la voie.
	 */
	@Override
	public Rail getById(int id) throws ApplicationException {

		try {
			return daoRail.getById(id);
		} catch (EmptyResultDataAccessException e) {
			throw new RailNotFoundException(
					"Hub : Impossible de trouver la voie avec cet identifiant.");
		} catch (DataAccessException e) {
			throw new DaoApplicationException(e);
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
	}
}
